package org.example.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONUtil;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.BuildImageCmd;
import org.example.ResponseResult;
import org.example.callback.BuildLogCallback;
import org.example.factory.DockerFileTypeFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Date: 2025/7/28 08:57
 */
@RestController
@RequestMapping("/v1/docker-java")
public class DockerJavaController {

    @Autowired
    private List<DockerFileTypeFactory> fileTypeFactories;

    @Autowired
    private DockerClient dockerClient;


    @PostMapping("/buildImage")
    public ResponseEntity<Object> buildImage(@RequestBody Map<String, Object> params) {
        Object dockerfileType = params.get("dockerfileType");
        if (CollectionUtils.isEmpty(fileTypeFactories)) {
            return ResponseEntity.ok(ResponseResult.buildFailure("没有配置dockerfile文件"));
        }
        Map<String, DockerFileTypeFactory> factoryMap = fileTypeFactories.stream()
                .collect(Collectors.toMap(DockerFileTypeFactory::getDockerFileType, Function.identity()));
        if (!factoryMap.containsKey(dockerfileType)) {
            return ResponseEntity.ok(ResponseResult.buildFailure("不存在该类型的dockerfile文件"));
        }

        DockerFileTypeFactory dockerFileTypeFactory = factoryMap.get(dockerfileType);
        String dockerfilePath = dockerFileTypeFactory.getDockerFilePath();
        String imageName = dockerFileTypeFactory.getImageName();
        Map<String, String> buildArgMap = dockerFileTypeFactory.dealWithBuildArgMap(params);

        File dockerfile = FileUtil.file(dockerfilePath);
        BuildLogCallback buildLogCallback = new BuildLogCallback(imageName);
        BuildImageCmd buildImageCmd = dockerClient.buildImageCmd()
                .withDockerfile(dockerfile)
                .withTags(Collections.singleton(imageName));
        //构建arg参数
        if (buildArgMap instanceof Map) {
            if (!ObjectUtils.isEmpty(buildArgMap)) {
                buildArgMap.forEach(buildImageCmd::withBuildArg);
            }
        }
        buildImageCmd.withNoCache(true).exec(buildLogCallback).awaitImageId();//不采用异步操作
        return ResponseEntity.ok(JSONUtil.parseObj(ResponseResult.buildSuccess(null)).toStringPretty());
    }
}
